#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <sstream>

using namespace std;

// 客户信息
struct Passenger {
    string name;
    int cabinClass; // 1, 2, or 3
};

// 航线信息
struct Flight {
    string destination;
    string flightNumber;
    string airplaneNumber;
    int dayOfWeek;
    int capacity;
    int remainingTickets;
    vector<Passenger> bookedPassengers;
    queue<Passenger> waitingList;
};

// 航空客运订票系统
class FlightBookingSystem {
private:
    vector<Flight> flights;
    string flight_filename; //存储航班的数据文件路径
    string passenger_filename; //存储乘客信息的文件路径
    string candidatepassenger_filename; //存储候补乘客的文件路径
    
    // 从文件加载航班信息
    void loadFlightsFromFile(const string& filename) {
        ifstream file(filename);
        if (!file.is_open()) {
            cout << "无法打开航班数据文件以加载" << endl;
            return;
        }
        
        // 从文件中读取航班信息并存储到 flights 向量中
        string line;
        while (getline(file, line)) {
            // 解析航班信息并添加到 flights 向量中
            // 格式：目的地,航班号,飞机号,星期几,容量,余票数
            Flight flight;
            size_t pos = line.find(',');
            flight.destination = line.substr(0, pos);
            line.erase(0, pos + 1);
            
            pos = line.find(',');
            flight.flightNumber = line.substr(0, pos);
            line.erase(0, pos + 1);
            
            pos = line.find(',');
            flight.airplaneNumber = line.substr(0, pos);
            line.erase(0, pos + 1);
            
            pos = line.find(',');
            flight.dayOfWeek = stoi(line.substr(0, pos));
            line.erase(0, pos + 1);
            
            pos = line.find(',');
            flight.capacity = stoi(line.substr(0, pos));
            line.erase(0, pos + 1);
            
            flight.remainingTickets = stoi(line);
            
            flights.push_back(flight);
        }
        file.close();
        // 从文件中读取航班信息并存储到 flights 向量中
        // 格式可以是 CSV、JSON 等，这里每行为一个航班信息
    }
    
    // 修改文件中的航班信息
    void modifyFlightInfo(const string& flightNumber,const string& airphoneNumber, const Flight& newFlightInfo) {
        for (Flight& flight : flights) {
            if (flight.flightNumber == flightNumber && flight.airplaneNumber == airphoneNumber) {
                // 找到对应航班，修改信息
                flight = newFlightInfo;
                break;
            }
        }
        
        // 更新航班数据文件
        ofstream outFile(flight_filename);
        if (!outFile.is_open()) {
            cout << "无法打开航班数据文件以写入" << endl;
            return;
        }
        
        // 将更新后的航班信息写入文件
        for (const Flight& flight : flights) {
            outFile << flight.destination << "," << flight.flightNumber << "," << flight.airplaneNumber << ","
            << flight.dayOfWeek << "," << flight.capacity << "," << flight.remainingTickets << endl;
        }
        outFile.close();
        
        cout << "航班信息已成功更新并写入文件" << endl;
    }
    
    
    // 从文件加载航班乘客信息
    void loadPassengersFromFile(const string& filename) {
        ifstream file(filename);
        if (!file.is_open()) {
            cout << "无法打开乘客数据文件以加载" << endl;
            return;
        }
        
        string line;
        while (getline(file, line)) {
            // 解析文件中的乘客信息
            stringstream ss(line);
            string flightNumber, passengerName;
            int cabinClass;
            ss >> flightNumber >> passengerName >> cabinClass;
            // 根据航班号查找对应的航班
            Flight* flight = findFlightByNumber(flightNumber);
            if (flight) {
                // 创建乘客对象
                Passenger passenger;
                passenger.name = passengerName;
                passenger.cabinClass = cabinClass;
                
                // 将乘客添加到航班的已订票乘客列表中
                flight->bookedPassengers.push_back(passenger);
            } else {
                cout << "错误：没有找到对应的航班！" << flightNumber << endl;
            }
        }
        file.close();
        
    }
    
    // 更新航班乘客信息到文件
    void updatePassengersToFile(const string& filename) {
        ofstream file(filename);
        if (!file.is_open()) {
            cout << "无法打开乘客数据文件以更新" << endl;
            return;
        }
        
        // 遍历所有航班
        for (const Flight& flight : flights) {
            // 将航班的已订票乘客信息写入文件
            for (const Passenger& passenger : flight.bookedPassengers) {
                file << flight.flightNumber << " " << passenger.name << " " << passenger.cabinClass << endl;
            }
        }
        
        file.close();
        cout << "乘客信息已成功更新并写入文件" << endl;
    }
    
    // 从文件加载候补乘客信息
    void loadCandidatePassengersFromFile(const string& filename) {
        ifstream file(filename);
        if (!file.is_open()) {
            cout << "无法打开候补乘客数据文件以加载" << endl;
            return;
        }
        
        string line;
        while (getline(file, line)) {
            // 解析文件中的候补乘客信息
            stringstream ss(line);
            string flightNumber, passengerName;
            int cabinClass;
            ss >> flightNumber >> passengerName >> cabinClass;
            // 根据航班号查找对应的航班
            Flight* flight = findFlightByNumber(flightNumber);
            if (flight) {
                // 创建乘客对象
                Passenger passenger;
                passenger.name = passengerName;
                passenger.cabinClass = cabinClass;
                
                // 将乘客添加到航班的候补乘客队列中
                flight->waitingList.push(passenger);
            } else {
                cout << "错误：没有找到对应的航班！" << flightNumber << endl;
            }
        }
        file.close();
        
    }
    
    // 更新航班候补乘客信息到文件
    void updateCandidatePassengersToFile(const string& filename) {
        ofstream file(filename);
        if (!file.is_open()) {
            cout << "无法打开候补乘客数据文件以更新" << endl;
            return;
        }
        
        // 遍历所有航班
        for (Flight& flight : flights) {
            //创建一个辅助队列
            queue<Passenger> temp;
            // 将航班的候补乘客信息写入文件
            while(!flight.waitingList.empty()){
                file << flight.flightNumber << " " << flight.waitingList.front().name << " " << flight.waitingList.front().cabinClass << endl;
                temp.push(flight.waitingList.front());
                flight.waitingList.pop();
            }
            while(!temp.empty()){
                flight.waitingList.push(temp.front());
                temp.pop();
            }
        }
        
        file.close();
        cout << "乘客信息已成功更新并写入文件" << endl;
    }
    
public:
    FlightBookingSystem(const string& filename1 , const string& filename2 , const string& filename3) {
        loadFlightsFromFile(filename1);
        flight_filename = filename1;
        loadPassengersFromFile(filename2);
        passenger_filename = filename2;
        loadCandidatePassengersFromFile(filename3);
        candidatepassenger_filename = filename3;
    }
    
    // 查询航班信息
    void queryFlight(const string& destination) {
        int i=0;
        cout << "查询航班信息：" << destination << endl;
        for (const auto& flight : flights) {
            if (flight.destination == destination) {
                cout << "目的地: " << flight.destination << endl;
                cout << "航班号: " << flight.flightNumber << endl;
                cout << "飞机号: " << flight.airplaneNumber << endl;
                cout << "星期几: " << flight.dayOfWeek << endl;
                cout << "剩余票数: " << flight.remainingTickets << endl;
                cout << endl;
                i++;
            }
        }
        if(i>0){
            return;
        }
        else{
            cout << "未找到目的地为 " << destination << " 的航班信息" << endl;
        }
    }
    
    // 订票
    void bookTicket(const string& flightNumber , int quantity) {
        // 遍历航班列表，查找匹配航班号的航班
        for (Flight& flight : flights) {
            if (flight.flightNumber == flightNumber) {
                
                // 检查航班是否还有余票
                if (flight.remainingTickets >= quantity) {
                    // 若余票足够，直接订票
                    for (int i = 0; i < quantity; ++i) {
                        // 模拟一个新乘客
                        Passenger passenger;
                        cout << "请输入乘客姓名: ";
                        cin >> passenger.name;
                        cout << "请输入预订购的座位类型:（输入数字1，2或3）";
                        cin >> passenger.cabinClass;
                        // 将乘客加入已订票乘客列表
                        flight.bookedPassengers.push_back(passenger);
                    }
                    // 更新剩余票额
                    flight.remainingTickets -= quantity;
                    updatePassengersToFile(passenger_filename);
                    modifyFlight(flight.flightNumber, flight.airplaneNumber, flight);
                    cout << "订票成功！" << endl;
                    return; // 订票成功，退出函数
                } else {
                    // 若余票不足，提示用户并提供其他选择
                    cout << "对不起，该航班剩余票额不足" << endl;
                    if(flight.remainingTickets > 0){
                        cout << "是否选择先订购剩余的票（票数无法满足您原先的订购票数）？"<<endl;
                        cout << "若是则输入1，否则输入0"<<endl;
                        cout << "请输入：";
                        int a_choice;
                        cin >> a_choice;
                        if(a_choice){
                            for (int i = flight.remainingTickets; i > 0 ; --i) {
                                // 模拟一个新乘客
                                Passenger passenger;
                                cout << "请输入乘客姓名: ";
                                cin >> passenger.name;
                                cout << "请输入预订购的座位类型:（输入数字1，2或3）";
                                cin >> passenger.cabinClass;
                                // 将乘客加入已订票乘客列表
                                flight.bookedPassengers.push_back(passenger);
                            }
                            //票数变更
                            quantity -= flight.remainingTickets;
                            flight.remainingTickets = 0;
                            updatePassengersToFile(passenger_filename);
                            modifyFlight(flight.flightNumber, flight.airplaneNumber, flight);
                        }
                    }
                        cout << "请输入数字1，2或3，进行选择相关功能"<<endl;
                label1:cout << "1.候补"<<endl;
                    cout << "2.查看所有可选择航班"<<endl;
                    cout << "3.退出该界面"<<endl;
                        cout << "请输入您的选项：";
                    int select;
                    cin >> select;
                    switch (select) {
                        case 1:{
                            for (int i = 0; i < quantity; ++i) {
                                // 模拟一个新乘客
                                Passenger passenger;
                                cout << "请输入乘客姓名: ";
                                cin >> passenger.name;
                                cout << "请输入预订购的座位类型:（输入数字1，2或3）";
                                cin >> passenger.cabinClass;
                                // 将乘客加入已订票乘客列表
                                flight.waitingList.push(passenger);
                            }
                            updateCandidatePassengersToFile(candidatepassenger_filename);
                            cout << "候补成功！"<<endl;
                            break;
                        }
                        case 2:{
                            string destination = flight.destination;
                            queryFlight(destination);
                            break;
                        }
                        case 3:{
                            break;
                        }
                        default:{
                            cout<<"输入值格式不对，请重新输入："<<endl;
                            goto label1;
                            break;
                        }
                    }
                    // 这里可以提供排队候补或其他可选择航班的功能
                    return; // 退出函数
                }
            }
        }
        // 若未找到匹配航班号的航班，提示用户重新输入
        cout << "未找到匹配航班号的航班，请重新输入" << endl;
    }
    
    
    // 退票
    void cancelTicket(const string& flightNumber, const string& passengerName) {
        // 遍历航班列表，查找匹配航班号的航班
        for (Flight& flight : flights) {
            if (flight.flightNumber == flightNumber) {
                // 在已订票乘客列表中查找匹配乘客姓名的乘客
                for (Passenger& passenger : flight.bookedPassengers) {
                    if (passenger.name == passengerName) {
                        // 找到匹配的乘客，执行退票操作
                        // 从已订票乘客列表中移除乘客
                        flight.bookedPassengers.erase(
                        remove_if(flight.bookedPassengers.begin(), flight.bookedPassengers.end(),[&](const Passenger& p) { return p.name == passengerName; }),flight.bookedPassengers.end());
                        cout << "退票成功！" << endl;
                        //判断是否执行候补功能
                        if(flight.remainingTickets==0){
                            //实行候补
                            flight.bookedPassengers.push_back(  flight.waitingList.front());
                            flight.waitingList.pop();
                            updateCandidatePassengersToFile(candidatepassenger_filename);
                        }
                        //不实行候补
                        else{
                            flight.remainingTickets++;//增加剩余票额
                        }
                        updatePassengersToFile(passenger_filename);
                        modifyFlight(flight.flightNumber, flight.airplaneNumber, flight);
                        return; // 退票成功，退出函数
                    }
                }
                // 若未找到匹配的乘客，提示用户重新输入
                cout << "未找到匹配的乘客，请重新输入" << endl;
                return; // 退出函数
            }
        }
        // 若未找到匹配航班号的航班，提示用户重新输入
        cout << "未找到匹配航班号的航班，请重新输入" << endl;
    }
    
    // 修改航班信息的公共接口
    void modifyFlight(const string& flightNumber, const string& airphoneNumber, Flight& newFlightInfo) {
        modifyFlightInfo(flightNumber,airphoneNumber,newFlightInfo);
    }
    
    // 显示航班信息
    void displayFlights() {
        cout << "所有航班信息：" << endl;
        for (const auto& flight : flights) {
            cout << "目的地: " << flight.destination << endl;
            cout << "航班号: " << flight.flightNumber << endl;
            cout << "飞机号: " << flight.airplaneNumber << endl;
            cout << "星期几: " << flight.dayOfWeek << endl;
            cout << "容量: " << flight.capacity << endl;
            cout << "剩余票数: " << flight.remainingTickets << endl;
            cout << endl;
        }
    }
    
    //判断能否修改航线数据
    bool ismodifyFlights(const string& flightNumber,const string& airphoneNumber){
        for (const auto& flight : flights) {
            if (flight.flightNumber == flightNumber && flight.airplaneNumber==airphoneNumber) {
                //当航班已经有乘客时，不能修改航班数据
                if(flight.remainingTickets<flight.capacity){
                    cout<<"已经有乘客订票，不能修改航班数据！"<<endl;                    return 0;
                }
                cout<<"可修改航班数据"<<endl;
                return 1;
            }
        }
        cout<<"未找到指定航班！"<<endl;
        return 0;
    }
    
    //上面声明的辅助函数，通过航班号找到对应航班的指针
    Flight* findFlightByNumber(const string& flightNumber) {
            for (Flight& flight : flights) {
                if (flight.flightNumber == flightNumber) {
                    return &flight;
                }
            }
            return nullptr;
        }
};

// 界面类
class GUI {
private:
    FlightBookingSystem& bookingSystem;
    
public:
    GUI(FlightBookingSystem& system) : bookingSystem(system) {}
    
    // 显示主菜单
    void showMainMenu() {
        cout << "欢迎使用航空客运订票系统" << endl;
        cout << "1. 查询航班信息" << endl;
        cout << "2. 订票" << endl;
        cout << "3. 退票" << endl;
        cout << "4. 修改航班信息" << endl;
        cout << "5. 显示所有航班信息" << endl;
        cout << "0. 退出系统" << endl;
        cout << "请选择功能: ";
    }
    
    // 运行界面
    void run() {
        int choice;
        do {
            showMainMenu();
            cin >> choice;
            cin.ignore(); // 清除输入缓冲区
            switch (choice) {
                case 1: {
                    string destination;
                    cout << "请输入目的地: ";
                    getline(cin, destination);
                    bookingSystem.queryFlight(destination);
                    break;
                }
                case 2: {
                    string flightNumber;
                    int quantity;
                    cout << "请输入航班号: ";
                    getline(cin, flightNumber);
                    cout << "请输入订票数量：";
                    cin >> quantity;
                    bookingSystem.bookTicket(flightNumber,quantity);
                    break;
                }
                case 3: {
                    string flightNumber, passengerName;
                    cout << "请输入航班号: ";
                    getline(cin, flightNumber);
                    cout << "请输入乘客姓名: ";
                    getline(cin, passengerName);
                    bookingSystem.cancelTicket(flightNumber, passengerName);
                    break;
                }
                case 4: {
                    // 输入要更新的航班数据
                    Flight flight;
                    cout << "请输入要修改的航班号: ";
                    cin >> flight.flightNumber;
                    cout << "请输入要修改的飞机号：";
                    cin >> flight.airplaneNumber;
                    // 判断能否修改航班数据(可修改的航班数据没有乘客订票）
                    if(bookingSystem.ismodifyFlights(flight.flightNumber, flight.airplaneNumber)){
                        cout << "此航班的终点站（更新后）：";
                        cin >> flight.destination;
                        cout << "此航班的飞行日（星期几）（更新后）：";
                        cin >> flight.dayOfWeek;
                        cout << "此航班的乘员定额（更新后）：";
                        cin >> flight.capacity;
                        flight.remainingTickets = flight.capacity;
                        //更新数据文件，修改航班数据
                        bookingSystem.modifyFlight(flight.flightNumber,flight.airplaneNumber,flight);
                        cout<< "修改成功！" << endl;
                    }
                    break;
                }
                case 5: {
                    bookingSystem.displayFlights();
                    break;
                }
                case 0: {
                    cout << "感谢使用，再见！" << endl;
                    break;
                }
                default: {
                    cout << "无效的选项，请重新输入" << endl;
                    break;
                }
            }
        } while (choice != 0);
    }
};

int main() {
    // 初始化航空客运订票系统，加载航班信息
    FlightBookingSystem bookingSystem("/Users/hefeiyu/Downloads/big_project/flights.JSON","/Users/hefeiyu/Downloads/big_project/passengers.JSON","/Users/hefeiyu/Downloads/big_project/candidatepassengers.JSON");
    
        // 初始化界面
        GUI gui(bookingSystem);

        // 运行界面
        gui.run();
    // TODO: 实现用户交互菜单，根据用户选择调用不同的系统功能
    return 0;
}
